home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / fonts / setfont2.1 < prev   
Text File  |  1988-12-28  |  12KB  |  380 lines

  1. Path: xanth!nic.MR.NET!csd4.milw.wisc.edu!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i102:  setfont - set system font v2.5
  5. Message-ID: <10933@swan.ulowell.edu>
  6. Date: 28 Dec 88 18:22:23 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 367
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: kim@uts.amdahl.com (Kim E. DeVaughn)
  12. Posting-number: Volume 2, Issue 102
  13. Archive-name: fonts/setfont25.1
  14.  
  15. [executable in comp.binaries.amiga.  ..Bob]
  16.  
  17. #    This is a shell archi
  18. ve.
  19. #    Remove everything above and including the cut line.
  20. #    Then run the rest of the file through sh.
  21. #----cut here-----cut here-----cut here-----cut here----#
  22. #!/bin/sh
  23. # shar:    Shell Archiver
  24. #    Run the following text with /bin/sh to create:
  25. #    SetFont.cp
  26. #    SetFont.doc
  27. # This archive created: Wed Dec 28 13:19:28 1988
  28. cat << \SHAR_EOF > SetFont.cp
  29. // =======================================================================
  30.  
  31. /* SetFont 2.5 - by Dave Haynie
  32.  
  33.             BIX:    hazy
  34.             Usenet:    {uunet|rutgers}!cbmvax!daveh
  35.             PLINK:    D-Dave H
  36.              Drink:    Guinness
  37.  
  38.    BUSINESS:
  39.  
  40.     This program is complete, real, and true public domain software.
  41.    Do with it what you will as long as you don't remove my name from it.
  42.    Feel free to enhance this as you see fit.  I may eventually make one
  43.    that's better....
  44.    
  45.    ABOUT IT:
  46.  
  47.         SetFont V2.5 cleans up all known bugs in SetFont V2.0, and it's
  48.    the first C++ version.  The code is GREATLY cleaned up and simplified
  49.    from SetFont V2.0.  I no longer free any fonts that were previously
  50.    set.  V2.0 did too much freeing, but even with that, it is possible
  51.    that another program could get a pointer to the font or font descriptor
  52.    in a window or screen and choke if that's freed.  That may not be good
  53.    behavior, but this way's safer.  A future version will probably track
  54.    fonts opened and closed by SetFont itsself so that it can reclaim some
  55.    of it's resources and still be reasonably safe.  Right now I have no
  56.    way of knowing if the font or descriptor I see is even really owned by
  57.    SetFont.
  58.  
  59.    CONFLICTS:
  60.  
  61.     There are a few potential problems the general notion of SetFont in 
  62.    the Amiga system.  First of all, many programs are written to support only
  63.    the topaz 8 (80 column) font (sloppy, I know, but that's life).  If you're
  64.    a 60 column user, you've probably experienced this before.  It's not a 
  65.    problem with the Amiga as a whole, since most of the system will adjust 
  66.    itself.  But it may be a problem with programs that have a fixed idea of 
  67.    what a font should look like.  Most 80 column fonts work with most 
  68.    applications, and an 80 column 8x8 font will work just about everywhere.  
  69.    Some programs, like CLI for instance, have trouble with proportionally-
  70.    spaced fonts.  The best thing to do is try out the font you like.  One 
  71.    final problem is that some applications ask the WorkBench screen to close 
  72.    when they start up.  It'll close if there's nothing else open on it, but 
  73.    when it re-opens, it'll restart with the Preferences-selected font, not 
  74.    the SetFont selected font.  Of course, preferences doesn't support 
  75.    arbitrary fonts (which is why this program is even necessary).  Oh well, 
  76.    maybe day.  
  77. */
  78.  
  79. #include <exec/types.h>
  80. #include <exec/io.h>
  81. #include <exec/ports.h>
  82. #include <exec/memory.h>
  83. #include <graphics/gfxbase.h>
  84. #include <graphics/text.h>
  85. #include <graphics/rastport.h>
  86. #include <libraries/dos.h>
  87. #include <libraries/dosextens.h>
  88. #include <intuition/intuition.h>
  89. #include <string.h>
  90. #include <ctype.h>
  91. #include <stdio.h>
  92. #include <stdlib.h>
  93.  
  94. // =========================================================================
  95.  
  96. // Miscellaneous stuff.
  97.  
  98. extern TextFont *OpenDiskFont(const TextAttr *);
  99.  
  100. inline BPTR CADDR(APTR cptr) { return BPTR(ULONG(cptr) >> 2); }
  101.  
  102. inline void fail(char *a, char *b = NULL) { printf(a,b); exit(10); }
  103.  
  104. inline MsgPort *contask(MsgPort *port) {
  105.    return (MsgPort *) ((port->mp_SigTask->ln_Type == NT_PROCESS)
  106.           ? ((Process *)port->mp_SigTask)->pr_ConsoleTask 
  107.           : NULL);
  108. }
  109.  
  110. // =========================================================================
  111.  
  112. // This is the "smart" font class.  SmartFont items stay around after the 
  113. // program exits if they appear to have been used.
  114.  
  115. class SmartFont {
  116.    private:
  117.       static BOOL aok;            // Font checks out    
  118.       TextAttr      sfattr;        // Font descriptor
  119.       
  120.    public:
  121.       SmartFont(char *n, UWORD s);
  122.  
  123.       TextFont *font() {
  124.          TextFont *f = OpenDiskFont(&sfattr);
  125.  
  126.          if (!f) f = OpenFont(&sfattr);
  127.          if (!f) fail("Font \"%s\" not found\n",sfattr.ta_Name);
  128.          return f;
  129.       }
  130.       TextAttr *attr() {
  131.          TextAttr *a = (TextAttr *)AllocMem(sizeof(TextAttr),MEMF_PUBLIC|MEMF_CLEAR);
  132.          a->ta_Name = (char *)AllocMem(strlen(sfattr.ta_Name)+1,MEMF_PUBLIC|MEMF_CLEAR);
  133.          strcpy(a->ta_Name,sfattr.ta_Name);
  134.          a->ta_YSize = sfattr.ta_YSize;
  135.          return a;
  136.       }
  137.       char *name() { return sfattr.ta_Name; }
  138.       UWORD size() { return sfattr.ta_YSize; }
  139. };
  140.  
  141. SmartFont::SmartFont(char *n, UWORD s = 8) {
  142.    strcat(strcpy(sfattr.ta_Name = new char[strlen(n)+6],n),".font");
  143.    sfattr.ta_YSize = (s>2)?s:8;
  144.    sfattr.ta_Style = sfattr.ta_Flags = 0;
  145.  
  146.    if (!aok) {
  147.       TextFont *f = font();
  148.       CloseFont(f);
  149.       aok = TRUE;
  150.    }
  151. }
  152.  
  153. // =========================================================================
  154.  
  155. // These classes manage the places that fonts are hidden.
  156.  
  157. // This is the basic place node
  158.  
  159. class PlaceNode : public Node {
  160.    private:
  161.       static Window *pwin;
  162.       static Screen *pscr;
  163.  
  164.    public:
  165.       PlaceNode();      
  166.       PlaceNode *next() { return (PlaceNode *)Node::next(); }
  167.  
  168.       void testwindow() { if (!pwin) fail("Window not found\n"); }
  169.       void testscreen() { if (!pscr) fail("Screen not found\n"); }
  170.  
  171.       Window *window()  { return pwin; }
  172.       Screen *screen()  { return pscr; }
  173.  
  174.       virtual void set(SmartFont *f) {
  175.          testwindow();
  176.          SetFont(window()->graphic(),f->font());
  177.          printf("\033c");              // Re-init window's conunit
  178.          (void)flushall();
  179.       }
  180. };
  181.  
  182. // Initialize the static stuff, once.
  183.  
  184. PlaceNode::PlaceNode() {
  185.    if (pwin) return;
  186.  
  187.    StandardPacket *packet = new StandardPacket;
  188.    InfoData *info = new InfoData;   
  189.    MsgPort *port = new StdPort;
  190.  
  191.   // Find the window
  192.    if (contask(port)) {
  193.       packet->sendio(contask(port),port,ACTION_DISK_INFO,CADDR(info));
  194.       (void)port->wait();
  195.       pwin = (Window *)info->id_VolumeNode;
  196.    } else 
  197.       pwin = NULL;
  198.    delete port;
  199.    delete info;
  200.    delete packet;
  201.  
  202.   // Find the screen
  203.    pscr = (pwin) ? pwin->screen() : NULL;
  204. }
  205.  
  206. // These are the derived special nodes, one for each "place".
  207.  
  208. #define WindowNode    PlaceNode
  209.  
  210. class ScreenNode : public PlaceNode {
  211.    public:
  212.       void set(SmartFont *f) {
  213.          testscreen();
  214.          if (strcmp(screen()->Font->ta_Name,f->name()) == 0)
  215.             screen()->Font->ta_YSize = f->size();
  216.          else
  217.             screen()->Font = f->attr();
  218.       }
  219. };
  220.  
  221. class TitleNode : public PlaceNode {
  222.    public:
  223.       void set(SmartFont *f) {
  224.          testscreen();
  225.          SetFont(screen()->graphic(),f->font());
  226.       }
  227. };
  228.  
  229. class BarNode : public PlaceNode {
  230.    public:
  231.       void set(SmartFont *f) {
  232.          testscreen();
  233.          SetFont(screen()->BarLayer->rp,f->font());
  234.       }
  235. };
  236.  
  237. // This is the place list, which links a number of place nodes, and also
  238. // manages to go work like finding windows, etc.
  239.  
  240. class PlaceList : public List {
  241.    public:
  242.       PlaceList(int argc, char **argv);   
  243.       PlaceNode *first() { return (PlaceNode *)List::first(); }
  244. };
  245.  
  246. // The PlaceList constructor does a great deal of the work.  It looks up
  247. // the window data, then parses the command line to build the place
  248. // list.
  249.  
  250. PlaceList::PlaceList(int argc, char **argv) {
  251.   // Parse our input arguments
  252.    for (short i = 0; i < argc; ++i)
  253.       switch (toupper(argv[i][0])) {
  254.          case 'B': add(new BarNode);        break;
  255.          case 'S': add(new ScreenNode);        break;
  256.          case 'T': add(new TitleNode);        break;
  257.          case 'W': add(new WindowNode);        break;
  258.          default :                break;
  259.       }
  260.    if (is_empty()) {
  261.       add(new BarNode);
  262.       add(new ScreenNode);
  263.       add(new TitleNode);
  264.       add(new WindowNode);
  265.    }
  266. }
  267.  
  268. // =========================================================================
  269.  
  270. // Prints help notice
  271.  
  272. void PrintNotice() {
  273.    printf("SetFont 2.5 by Dave Haynie\n\n");
  274.    printf("Usage: SetFont [fontname [point [place]]]\n");
  275.    printf("  where:\n");
  276.    printf("  \2331mfontname\2330m  is the font's name (e.g. \"topaz\")\n");
  277.    printf("  \2331mpoint\2330m     is the point size (default is 8)\n");
  278.    printf("  \2331mplace\2330m     pick the place, one or more of:\n");
  279.    printf("    \2331mBAR\2330m       set the barlayer font only\n");
  280.    printf("    \2331mSCREEN\2330m    set the screen font only\n");
  281.    printf("    \2331mTITLES\2330m    set the screen titles only\n");
  282.    printf("    \2331mWINDOW\2330m    set the window's font only\n\n");
  283.    printf("If no \2331mplace\2330m switch is given, everything is set.\n\n");
  284.    exit(0);
  285. }
  286.  
  287. // The main function
  288.  
  289. void main(int argc, char *argv[]) {
  290.   // Automatic help command
  291.    if (argc < 2 || argv[1][0] == '?') PrintNotice();
  292.  
  293.   // Process the command-line arguments, AmigaDOS style.
  294.    PlaceList *plist = new PlaceList(argc-2,&argv[3]);
  295.  
  296.   // Get the font if it's there.
  297.    SmartFont *font = new SmartFont(argv[1],atoi(argv[2]));
  298.    
  299.   // Here we apply all the requested changes.
  300.    for (PlaceNode *n = plist->first(); n->next(); n = n->next()) n->set(font);
  301.  
  302.   // And we're done!
  303.    exit(0);
  304. }
  305. SHAR_EOF
  306. cat << \SHAR_EOF > SetFont.doc
  307.  
  308.  
  309.             SetFont V2.5 by Dave Haynie
  310.  
  311.  
  312.     SetFont V2.5 is a public domain program designed to allow the system
  313. font of the Amiga to be changed in various different ways.  The program is
  314. called from a shell or startup-sequence script, and has the form:
  315.  
  316.     SetFont [fontname [point [places]]]
  317.  
  318.     where:
  319.  
  320.         fontname    Specifys the name of a standard Amiga 
  321.                 bitmapped font from the FONTS: directory.
  322.                 While any font can in theory be used, the
  323.                 system has trouble with very large ones,
  324.                 and some programs may have trouble with any
  325.                 font that's not 8x8.
  326.  
  327.         point        Specifys the height of the font, in pixels.
  328.                 If that actual size isn't found, the closest
  329.                 available is substituted.  The default for
  330.                 this is 8.
  331.  
  332.         places        There are several places the system keeps
  333.                 fonts.  When you change to a working font
  334.                 you may want that font everywhere in the
  335.                 system, in which case, no specifier is set.
  336.                 Otherwise, the following places are known
  337.                 by SetFont:
  338.  
  339.             BAR        This is the "BarLayer" font for the WorkBench
  340.                 screen.  Among other things, the text in any
  341.                 string gadgets BEFORE you select them comes
  342.                 from this location.
  343.  
  344.             SCREEN    This specified the default font for the 
  345.                 WorkBench screen.  All menus and newly built
  346.                 windows will inherit this font as their 
  347.                 default font.  Technically speaking, this is
  348.                 a font descriptor stored in the screen
  349.                 structure.
  350.  
  351.             TITLES    This specifies the font that's mainly used
  352.                 for window title bars.  Technically speaking,
  353.                 this specifies the font of the screen's
  354.                 RastPort.
  355.  
  356.             WINDOW    This specifies the font for the current window.
  357.                 It will case that window to be cleared.  The
  358.                 reason for this is that the window's font is
  359.                 not a default, but inherited from the screen
  360.                 and stored in the window's ConUnit.  That
  361.                 screen clear is the result of rebuilding the
  362.                 window's ConUnit to bring in the new font.
  363.  
  364.     And that's about it.  Please feel free to use this program and the
  365. source code as you see fit.  If you find any bugs, please let me know about
  366. them.
  367.  
  368.         -Dave Haynie
  369.  
  370.         PLINK  :    D-Dave H
  371.         bix    :    hazy
  372.         usenet :    {rutgers,uunet}!cbmvax!daveh
  373. SHAR_EOF
  374. #    End of shell archive
  375. exit 0
  376. -- 
  377. Bob Page, U of Lowell CS
  378.  Dept.  page@swan.ulowell.edu  ulowell!page
  379. Have five nice days.
  380.